#pragma once

#include <typeinfo>
#include <iostream>
#include <cassert>

class Any
{
private:
    void Swap(Any& other)
    {
        std::swap(_content, other._content);
    }
public:
    Any()
     : _content(nullptr)
    {
    }
    template<class T>
    Any(const T& val)
     : _content(new PlaceHolder<T>(val))
    {
    }
    Any(const char* val)
     : _content(new PlaceHolder<std::string>(val))
    {
    }
    Any(const Any& other)
    {
        if (&other == this) // 不能拿自己拷贝构造自己，因为这是深拷贝
            return;
        _content = other._content ? other._content->clone() : nullptr;
    }
    Any(Any&& other)
    {
        Swap(other);
    }
    template<class T>
    Any& operator=(const T& val)
    {
        Any tmp(val);
        Swap(tmp);
        return *this;
    }
    Any& operator=(const Any& other)
    {
        assert(&other != this); // 不能拿自己赋值自己，因为这是深拷贝
        Any tmp(other);
        Swap(tmp);
        return *this;
    }
    Any& operator=(Any&& other)
    {
        Swap(other);
        return *this;
    }
    template<class T>
    T* Get() // 返回子类对象保存的数据指针
    {
        if (_content->type() != typeid(T))  return nullptr;
        return &dynamic_cast<PlaceHolder<T>*>(_content)->_val;
    }
    ~Any()
    {
        delete _content;
    }
private:
    class Holder
    {
    public:
        virtual ~Holder() = default; // 这个一定要！因为Any对象中的成员是父类指针，父类指针才能访问子类的析构函数，正确析构
        virtual const std::type_info& type() = 0;  // 获取子对象保存的数据结构
        virtual Holder* clone() = 0;        // 针对当前的对象自身，克隆出一个新的子类对象
    };
    template<class T>
    class PlaceHolder : public Holder
    {
    public:
        PlaceHolder(const T& val)
         : _val(val)
        {
        }

        virtual const std::type_info& type() override
        {
            return typeid(T);
        }

        virtual Holder* clone() override
        {
            return new PlaceHolder(_val);
        }
    public:
        T _val;
    };
    Holder* _content;
};